﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Threading;
using System.Collections;

namespace MainForm
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(SomeExceptionHandler);

        }

        private SqlConnection conn; //= new SqlConnection(@"Server=SDATA;Database=SecurityFA;Integrated Security=True");
        private int countChild = 0;
        private bool isProgrammer = false;
        private string dir_source = @"\\fs\КОРПОРАТИВНЫЙ ФАЙЛОВЫЙ РЕСУРС\Ярлыки программ\Аналитическая система";

        static void SomeExceptionHandler(object sender, UnhandledExceptionEventArgs args)
        {
            Exception e = (Exception)args.ExceptionObject;
            MessageBox.Show(e.ToString());
            // TODO: Обработать исключение
        }

        private string GetServ(string filename)
        {
            string str = "";
            try
            {
                using (StreamReader streamReader = new StreamReader(filename))
                {
                    while (!streamReader.EndOfStream)
                    {
                        str += streamReader.ReadLine();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Метод MainForm.GetServ(string filename)\n" + ex.Message);
                str = "SDATA2";
            }
            return str;
        }

        private bool ExistConn(SqlConnection sqlcon)
        {
            try
            {
                sqlcon.Open();
                sqlcon.Close();
            }
            catch(Exception ex)
            {
                MessageBox.Show("Соединение с сервером отсутсвует, обратитесь к разработчику\nМетод MainForm.ExistConn(SqlConnection sqlcon)\n" + ex.Message);
                return false;
            }
            return true;
        }

        private void LoaderUpdate()
        {
            try
            {
                isProgrammer = false;
                SqlCommand progr = conn.CreateCommand();
                progr.CommandText = "IsProgrammer";
                conn.Open();
                if (Convert.ToInt32(progr.ExecuteScalar()) == 1) isProgrammer = true;

                SqlCommand myCommand = conn.CreateCommand();
                myCommand.CommandType = CommandType.StoredProcedure;
                myCommand.CommandText = @"GetLoaderVersion";
                SqlParameter retValue = myCommand.Parameters.Add("@c", SqlDbType.Int);
                retValue.Direction = ParameterDirection.ReturnValue;
                
                int tmp = myCommand.ExecuteNonQuery();
                if (tmp != 0)
                    if ((int)retValue.Value == 1)
                    {
                        SqlDataReader dataReader = myCommand.ExecuteReader();
                        dataReader.Read();
                        string lv = dataReader.GetString(dataReader.GetOrdinal("Version"));
                        dataReader.Close();
                        conn.Close();
                        string dir = Directory.GetCurrentDirectory();
                        string[] exefiles = Directory.GetFiles(dir, "loader.exe", SearchOption.AllDirectories);
                        string lv_current = "";
                        if (exefiles.Length > 0) lv_current = FileVersionInfo.GetVersionInfo(exefiles[0]).FileVersion.ToString();
                        if (lv.ToLower() != lv_current.ToLower() || lv_current == "")
                        {
                            Array.Resize(ref exefiles, 0);
                            exefiles = Directory.GetFiles(dir_source, "loader.exe", SearchOption.AllDirectories);
                            if (exefiles.Length > 0)
                            {
                                if (exefiles.Length == 1)
                                {
                                    string lv_source = FileVersionInfo.GetVersionInfo(exefiles[0]).FileVersion.ToString();
                                    if (lv.ToLower() == lv_source.ToLower())
                                    {
                                        while (CheckLoaderProcess() > 0)
                                        {
                                            Thread.Sleep(100);
                                        }
                                        File.Copy(dir_source + @"\loader.exe", dir + @"\Loader.exe", true);
                                    }
                                    else MessageBox.Show("Версия файла на сервере Loader.exe не совпадает с актуальной версией");
                                }
                                else MessageBox.Show("На сервере обновлений несколько файлов Loader.exe");
                            }
                            else MessageBox.Show("На сервере обновлений отсутсвует файл Loader.exe");
                            Array.Resize(ref exefiles, 0);
                        }
                    }
                    else MessageBox.Show("В таблице слишком много версий файла Loader.exe");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Метод MainForm.LoaderUpdate()\n" + ex.Message);
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            try
            {
                if (!File.Exists(@"serv.txt")) File.Copy(@"\\fs\КОРПОРАТИВНЫЙ ФАЙЛОВЫЙ РЕСУРС\Ярлыки программ\Аналитическая система\serv.txt", @"serv.txt");
                conn = new SqlConnection(@"Server=" + GetServ("serv.txt") + ";Database=SecurityFA;Integrated Security=True");
                if (ExistConn(conn))
                {
                    LoaderUpdate();
                }
                else
                {
                    if (MessageBox.Show("Программу можно запустить без подключения к серверу,\nно многие или даже все инструменты не будут работать!\nЗапустить программу?", "Внимание!", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No)
                        this.Close();
                }
                LoadDLL();
                timer1.Start();
                if (conn.State != ConnectionState.Closed) conn.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Метод MainForm.MainForm_Load(object sender, EventArgs e)\n" + ex.Message);
                this.Close();
            }
        }

        private void LoadDLL()
        {
            try
            {
                string dir = Directory.GetCurrentDirectory();
                string[] filePaths = Directory.GetFiles(dir, "*.dll", SearchOption.AllDirectories);
                ToolStripMenuItem[] tsmi = new ToolStripMenuItem[] { };
                ToolStripMenuItem infwindow = new ToolStripMenuItem();
                for (int n = 0; n < filePaths.Length; n++)
                {
                    if (Path.GetDirectoryName(filePaths[n]) != dir + @"\Support")
                    {
                        string s = Path.GetDirectoryName(filePaths[n]);

                        try
                        {
                            Assembly asm = Assembly.LoadFile(filePaths[n]);
                            Type t = asm.GetType(@"template_dll.ChildForm");
                            object result = null;
                            Array.Resize(ref tp, tp.Length + 1);
                            tp[tp.Length - 1].path = filePaths[n];
                            tp[tp.Length - 1].toolposname = t.GetField("ToolPosName").GetValue(result).ToString();
                            tp[tp.Length - 1].toolname = t.GetField("ToolName").GetValue(result).ToString();
                            tp[tp.Length - 1].toolpostext = t.GetField("ToolPosText").GetValue(result).ToString();  
                            if (isProgrammer)
                                tp[tp.Length - 1].tooltext = t.GetField("ToolText").GetValue(result).ToString() + " [" + tp[tp.Length - 1].toolname + "]";
                            else
                                tp[tp.Length - 1].tooltext = t.GetField("ToolText").GetValue(result).ToString();
                            
                            ToolStripMenuItem tposname = new ToolStripMenuItem();
                            tposname.Text = tp[tp.Length - 1].toolpostext;
                            tposname.Name = tp[tp.Length - 1].toolposname;
                            ToolStripMenuItem tname = new ToolStripMenuItem();
                            tname.Text = tp[tp.Length - 1].tooltext;
                            tname.Name = tp[tp.Length - 1].toolname;
                            
                            tname.Click += new EventHandler(ToolClick);

                            tposname.DropDownItems.AddRange(new ToolStripItem[] { tname });
                            bool fl = false;
                            for (int i = 0; i < tsmi.Length; i++)
                            {

                                if (tsmi[i].Text == tposname.Text)
                                {
                                    tsmi[i].DropDownItems.AddRange(new ToolStripItem[] { tname });
                                    fl = true;
                                }
                            }
                            if (!fl)
                            {
                                Array.Resize(ref tsmi, tsmi.Length + 1);
                                tsmi[tsmi.Length - 1] = tposname;
                            }
                            if (tname.Name == "Information") infwindow = tname;
                            
                        }
                        catch(Exception)
                        {           
                        }
                    }
                }
                for (int j = 0; j < tsmi.Length; j++)
                {
                    menuStrip1.Items.AddRange(new ToolStripItem[] { tsmi[j] });
                }
                if (infwindow != null) ToolClick(infwindow, new EventArgs());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private struct ToolsParam
        {
            public string path;
            public string toolposname;
            public string toolpostext;
            public string toolname;
            public string tooltext; 
        }

        private ToolsParam[] tp = new ToolsParam[] { };

        private void ToolClick(object sender, EventArgs e)
        {
            try
            {
                for (int i = 0; i < tp.Length; i++)
                {
                    if ((sender as ToolStripMenuItem).Text == tp[i].tooltext && (sender as ToolStripMenuItem).Name == tp[i].toolname)
                    {
                        Assembly asm = Assembly.LoadFile(tp[i].path);
                        Type t = asm.GetType(@"template_dll.ChildForm");
                        object result = null;
                        object[] arguments = { this };
                        result = t.InvokeMember("DisplayForm", BindingFlags.InvokeMethod, null, result, arguments);
                        
                        Button chFormButton = new Button();
                        chFormButton.Height = flowLayoutPanel1.Height - flowLayoutPanel1.Margin.Bottom - flowLayoutPanel1.Margin.Top;
                        chFormButton.Text = tp[i].tooltext;
                        chFormButton.AutoSize = true;
                        chFormButton.Click += new EventHandler(chFormButton_Click);
                        flowLayoutPanel1.Controls.Add(chFormButton);
                        countChild++;

                        if(conn.State == ConnectionState.Closed)
                            conn.Open();
                        SqlCommand myCommand = conn.CreateCommand();
                        myCommand.CommandType = CommandType.StoredProcedure;
                        myCommand.CommandText = @"insLogs";
                        SqlParameter retValue = myCommand.Parameters.Add("@nameProc", SqlDbType.VarChar);
                        retValue.SqlValue = tp[i].tooltext;
                        SqlDataReader dataReader = myCommand.ExecuteReader();
                        conn.Close();

                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        

        private void chFormButton_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < (sender as Control).Parent.Controls.Count; i++)
            {
                if ((sender as Control).Parent.Controls[i] == (sender as Control))
                {
                    Form actChl = this.ActiveMdiChild;
                    if (actChl != null)
                    {
                        if (actChl == this.MdiChildren[i])
                        {
                            if (this.MdiChildren[i].WindowState == FormWindowState.Maximized)
                            {
                                this.MdiChildren[i].WindowState = FormWindowState.Minimized;
                                //this.MdiChildren[i].Visible = false;
                            }
                            else
                            {
                                this.MdiChildren[i].Activate();
                                this.MdiChildren[i].WindowState = FormWindowState.Maximized;
                                //this.MdiChildren[i].Visible = true;
                            }
                        }
                        else
                        {
                            this.MdiChildren[i].WindowState = FormWindowState.Maximized;
                            //this.MdiChildren[i].Visible = true;
                        }
                    }
                }
            }
        }

        private int CheckLoaderProcess()
        {
            Process[] AllProcesses = Process.GetProcessesByName("loader");

            return AllProcesses.Length;
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            foreach (Form frm in this.MdiChildren)
            {
                frm.Close();
            }
        }

        private void toolStripMenuItem3_Click(object sender, EventArgs e)
        {
            foreach (Form f in this.MdiChildren)
            {
                f.WindowState = FormWindowState.Normal;
            }
            this.LayoutMdi(MdiLayout.Cascade);
        }

        private void toolStripMenuItem4_Click(object sender, EventArgs e)
        {
            foreach (Form f in this.MdiChildren)
            {
                f.WindowState = FormWindowState.Normal;
            }
            this.LayoutMdi(MdiLayout.TileHorizontal);
        }

        private void toolStripMenuItem5_Click(object sender, EventArgs e)
        {
            foreach (Form f in this.MdiChildren)
            {
                f.WindowState = FormWindowState.Normal;
            }
            this.LayoutMdi(MdiLayout.TileVertical);
        }

        private void toolStripMenuItem6_Click(object sender, EventArgs e)
        {
            foreach (Form f in this.MdiChildren)
            {
                f.WindowState = FormWindowState.Minimized;
            }
            //for (int i = 0; i < this.MdiChildren.Length; i++)
            //{
            //    this.MdiChildren[i].WindowState = FormWindowState.Minimized;
            //}
        }

        private void toolStripMenuItem7_Click(object sender, EventArgs e)
        {
            foreach (Form f in this.MdiChildren)
            {
                f.WindowState = FormWindowState.Maximized;
            }
            
        }

        private void toolStripMenuItem7_Click_1(object sender, EventArgs e)
        {
            foreach (Control c in flowLayoutPanel1.Controls)
            {
                MessageBox.Show(c.Location.X.ToString() + " " + c.Location.Y.ToString() + "\n" + c.Height.ToString() + " " + c.Width.ToString());
            }
        }

        private void flowLayoutPanel1_ControlAdded(object sender, ControlEventArgs e)
        {
            ResizeButtons();
        }

        private void flowLayoutPanel1_SizeChanged(object sender, EventArgs e)
        {
            ResizeButtons();
        }

        private void ResizeButtons()
        {
            int width = 0;
            foreach (Control c in flowLayoutPanel1.Controls)
            {
                (c as Button).AutoSize = true;
                width += c.Width;
            }
            width += 6 * flowLayoutPanel1.Controls.Count;

            if(width > 0)
                if (width < flowLayoutPanel1.Width)
                {
                    foreach (Control c in flowLayoutPanel1.Controls)
                        (c as Button).AutoSize = true;
                }
                else
                {
                    double k = (double)flowLayoutPanel1.Width / (double)width;
                    foreach (Control c in flowLayoutPanel1.Controls)
                    {
                        double kk = ((c as Button).Width * k);
                        (c as Button).AutoSize = false;
                        int ii = (int)kk - 10;
                        (c as Button).Width = ii;
                    }
                }
        }

        private void flowLayoutPanel1_ControlRemoved(object sender, ControlEventArgs e)
        {
            ResizeButtons();
        }

        private void MainForm_MdiChildActivate(object sender, EventArgs e)
        {
            //if(this.MdiChildren.Length < flowLayoutPanel1.Controls.Count)
            //    for (int i = 0; i < MdiChildren.Length; i++)
            //    {
            //        if (flowLayoutPanel1.Controls[i].Text != this.MdiChildren[i].Text)
            //        {
            //            flowLayoutPanel1.Controls.RemoveAt(i);
            //        }
            //    }

            //if (flowLayoutPanel1.Controls.Count - this.MdiChildren.Length == 1)
            //    flowLayoutPanel1.Controls.RemoveAt(flowLayoutPanel1.Controls.Count - 1);    
            
            //MessageBox.Show((sender as Form).ActiveMdiChild.Text + "\n" + (sender as Form).MdiChildren.Length.ToString());

        }

        private void MainForm_Paint(object sender, PaintEventArgs e)
        {
          
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            try
            {
                if (this.MdiChildren.Length != flowLayoutPanel1.Controls.Count)
                {
                    if (this.MdiChildren.Length < flowLayoutPanel1.Controls.Count)
                        for (int i = 0; i < MdiChildren.Length; i++)
                        {
                            if (flowLayoutPanel1.Controls[i].Text != this.MdiChildren[i].Text)
                            {
                                flowLayoutPanel1.Controls.RemoveAt(i);
                                break;
                            }
                        }

                    if (flowLayoutPanel1.Controls.Count - this.MdiChildren.Length == 1)
                        flowLayoutPanel1.Controls.RemoveAt(flowLayoutPanel1.Controls.Count - 1);
                    if (this.MdiChildren.Length == 0 && flowLayoutPanel1.Controls.Count > 0)
                        while (flowLayoutPanel1.Controls.Count > 0)
                            flowLayoutPanel1.Controls.RemoveAt(0);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("MainForm, метод timer1_Tick\n" + ex.Message);
            }
        }
    }
}
